<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0059)http://203.162.17.98/weblh/suutam/2002/vovisoft/msnet/7.htm -->
<HTML><HEAD><TITLE>Bài 7</TITLE>
<META http-equiv=Content-Language content=en-us>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<META content="Le Hoan" name=Author>
<META content="MSHTML 5.50.4134.100" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId>
<META 
content="computer, software, games, vietnam, viet nam, tin hoc, le hoan, pclehoan, ktlehoan, vietnamese, download, saigon, freeware, lehoanpc, mailing list, may tinh, phan cung, phan mem, kien thuc, hop thu, internet, weblh, unicode, Forum, chat, diendan, dien dan" 
name=keywords>
<META 
content="Pho bien kien thuc, huong dan su dung phan cung, phan mem may tinh, game. Download software free. Link website Vietnam, forum, chat, mailing list..." 
name=description></HEAD>
<BODY>
<CENTER>
<P><A href="http://www.vovisoft.com/"><IMG height=77 alt="Logo of Vovisoft" 
src="7_files/vs-logo4_10.gif" width=102 border=0> </A><FONT face=Tahoma></P>
<H2><FONT face=Tahoma color=#800000>Bài 7</FONT></H2>
<H2><FONT face=Tahoma color=#800000>Những chức năng Đối Tượng mới của VB.NET 
(phần IV)</FONT></H2></CENTER></FONT><FONT face=Arial>
<BLOCKQUOTE>
  <BLOCKQUOTE>
    <H3><FONT color=green size=2>Dùng OO trong VB.NET</FONT></H3>
    <H3><FONT color=blue size=2>Shared class members ( Các thành viên để dùng 
    chung của class)</FONT></H3>
    <P><FONT size=2>Mặc dù Object rất hiệu năng và hữu ích, có khi ta chỉ muốn 
    truy cập các variables hay methods của một class để làm việc mà không cần 
    phải instantiate một Object nào cả. Tức là y như trong quá khứ, khi viết 
    VB6, ta dùng các variables hay methods của một BAS Module. Đại khái giống 
    như thay vì ký giao kèo với một thầu (Object) để thực hiện một công trình, 
    ta chỉ muốn mướn thợ hay chuyên viên làm việc gia công ( gọi các methods) 
    thôi.</FONT></P>
    <H3><FONT color=#800000 size=2>Shared Methods</FONT></H3>
    <P><FONT size=2>Trong VB.NET chẳng những một Class có các methods và 
    properties thông thường như ta đã thấy - tức là những methods và properties 
    của một Object ta có thể dùng ngay sau khi Object ấy thành hình qua quá 
    trình instantiation - mà còn có các methods và properties ta có thể dùng mà 
    không cần phải tạo ra một instance nào từ Class. Chúng được gọi là <B>shared 
    methods</B>. ( Trong các ngôn ngữ lập trình khác các methods nầy còn được 
    gọi là <B>static methods</B> hay <B>class methods</B>).<BR><BR>Ta không thể 
    truy cập một shared method qua một Object như method bình thường, nhưng phải 
    dùng trực tiếp <B>tên của class</B>. Thí dụ sau đây sẽ minh họa điều 
    nầy:</FONT></P></FONT><FONT face=Tahoma>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> Math 
   <FONT color=blue>Shared</FONT> <FONT color=blue>Function</FONT> Add( <FONT color=blue>ByVal</FONT> x <FONT color=blue>As</FONT> Single, <FONT color=blue>ByVal</FONT> y <FONT color=blue>As</FONT> Single) <FONT color=blue>As</FONT> <FONT color=blue>Single</FONT> 
      <FONT color=blue>Return</FONT> x + y 
   <FONT color=blue>End</FONT> <FONT color=blue>Function</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Sau khi định nghĩa <B>Class Math</B>, ta có thể dùng <B>Shared Function 
    Add</B> mà không cần instantiate một Object thuộc class Math như 
    sau:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Dim</FONT> Result <FONT color=blue>As</FONT> <FONT color=blue>Single</FONT> 
result = Math.Add(12.5, 36.8) 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Để ý thay vì dùng một object variable ta dùng thẳng tên của class Math để 
    truy cập method Add. Với một method bình thường thì làm như thế sẽ bị syntax 
    error, nhưng trong trường hợp nầy thì không sao.<BR><BR>Ta cũng có thể 
    <B>overload</B> shared methods, tức là có thể code nhiều shared methods với 
    cùng một tên nhưng có những parameter lists khác nhau.<BR><BR>Phạm vi hoạt 
    động bình thường (<B>Default Scope</B>) của shared methods là <B>Public</B>. 
    Tuy nhiên ta có thể giới hạn việc truy cập chúng bằng cách dùng những Access 
    Modifiers như <B>Friend, Protected</B> hay <B>Private</B>. Thật ra khi 
    overloading một shared method ta có thể dùng những scopes khác nhau cho mỗi 
    shared method.<BR><BR>Có một thí dụ về shared method từ .NET system class 
    libraries. Để mở một text file theo mode input, điển hình ta dùng shared 
    method trong <B>File</B> class như sau:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Dim</FONT> inFile <FONT color=blue>As</FONT> StreamReader = File.OpenText("words.txt") 
<FONT color=blue>Dim</FONT> strIn <FONT color=blue>As</FONT> <FONT color=blue>String</FONT> <BR>
strIn = inFile.ReadLine() 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Ở đây không có object File nào được tạo ra. Method 
    <B>OpenText</B> là một shared Function, nó mở input text file 
    <B>words.txt</B> và cho ta một object loại StreamReader tên <B>inFile</B> để 
    ta dùng sau đó. </FONT></P>
    <H3><FONT color=#800000 size=2>Shared Variables</FONT></H3>
    <P><FONT size=2>Đôi khi ta muốn tất cả objects của cùng một class đều dùng 
    chung một variable. Ta có thể thực hiện việc ấy với <B>shared 
    variables</B>.<BR><BR>Một shared variable được khai báo với keyword 
    <B>shared</B> giống như shared method:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> MyCounter 
   <FONT color=blue>Private</FONT> <FONT color=blue>Shared</FONT> mintCount <FONT color=blue>As</FONT> <FONT color=blue>Integer</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Ta có thể cho shared variable một scope Public hay Private tùy ý, nhưng 
    By Default, scope của shared variables là <B>Private</B>, khác với shared 
    methods thì By Default là <B>Public</B>.<BR><BR>Điểm quan trọng của shared 
    variables là chúng được dùng chung giữa mọi instances (objects) của cùng một 
    class. Dưới đây là một thí dụ trong đó ta giữ cái counter có trị số tăng 
    thêm 1 mỗi lần có một instance mới của <B>class MyCounter</B>. Bất cứ lúc 
    nào ta cũng có thể biết có bao nhiêu objects đã được tạo ra bằng cách đọc 
    <B>property Count</B>:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> MyCounter 
   <FONT color=blue>Private</FONT> <FONT color=blue>Shared</FONT> mintCount <FONT color=blue>As</FONT> <FONT color=blue>Integer</FONT> 

   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> New() 
      mintCount += 1 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 

   <FONT color=blue>Public</FONT> <FONT color=blue>ReadOnly</FONT> <FONT color=blue>Property</FONT> Count() <FONT color=blue>As</FONT> <FONT color=blue>Integer</FONT> 
      <FONT color=blue>Get</FONT> 
         <FONT color=blue>Return</FONT> mintCount 
      <FONT color=blue>End</FONT> <FONT color=blue>Get</FONT> 
   <FONT color=blue>End</FONT> <FONT color=blue>Property</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Như thế, nếu ta chạy client code dưới đây nó sẽ hiển thị kết quả là 
    <B>3</B>:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Protected</FONT> <FONT color=blue>Sub</FONT> Button1_Click( <FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> Object, <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> Button1.Click 
   <FONT color=blue>Dim</FONT> obj <FONT color=blue>As</FONT> MyCounter 

   obj = <FONT color=blue>New</FONT> MyCounter() 
   obj = <FONT color=blue>New</FONT> MyCounter() 
   obj = <FONT color=blue>New</FONT> MyCounter() 
   MsgBox(obj.Count, MsgBoxStyle.Information, "Counter") 

<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Nếu ta chạy code thêm hai lần nữa, ta sẽ có <B>6</B> và 
    <B>9</B>. Hể ta còn chạy chương trình thì cái counter còn làm việc. Khi ta 
    chấm dứt chương trình thì cái counter sẽ biến mất. <BR><BR>Bạn có thể <A 
    href="http://www.vovisoft.com/dotNET/Bai07/SharedCounter.zip">Download 
    source code</A> của program nầy tại đây. </FONT></P>
    <H3><FONT color=#800000 size=2>Global values</FONT></H3>
    <P><FONT size=2>Một cách dùng rất thông dụng khác của shared variable là xem 
    nó như một loại <B>Global variable</B>. Khi dùng scope Public ta sẽ có một 
    dạng tương đương với VB6 Global variable trong một BAS Module. Thí dụ 
    như:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> GlobalData 
   <FONT color=blue>Public</FONT> <FONT color=blue>Shared</FONT> TotalCost <FONT color=blue>As</FONT> <FONT color=blue>Single</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Sau đó ta có thể dùng variable nầy khắp nơi trong client 
    code:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial>GlobalData.TotalCost += 45.60 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <H3><FONT color=blue size=2>Events</FONT></H3>
    <H3><FONT color=#800000 size=2>Raising Event để xử lý trong một Project 
    khác</FONT></H3>
    <P><FONT size=2>VB.NET không hổ trợ <B>Events</B> từ đời cha đến đời con 
    theo đúng nguyên tắc thừa kế. Nếu một BaseClass định nghĩa một Public Event 
    thì ta chỉ có thể <B>raise</B> event ấy trong code của BaseClass thôi chớ 
    không thể <B>raise</B> event ấy trong SubClass nào của BaseClass 
    ấy.<BR><BR>Khác với methods, ta không thể <B>overload</B> một Event, tức là 
    không thể dùng một tên cho hai Events có parameter list khác nhau.<BR><BR>Ta 
    có thể tạo một Class Library Project với một Class trong đó có raise một 
    Event rồi tạo một project khác trong đó có code để đón nhận và xử lý Event 
    ấy.<BR><BR>Để thử việc nầy bạn hãy tạo một Class Library Project mới với tên 
    <B>ClassLibrary1</B> về viết những dòng code định nghĩa <B>Class Class1</B> 
    với <B>Event TheEvent</B> và <B>Sub LàmViệc</B> để raise Event như 
    sau:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> Class1 
   <FONT color=blue>Public</FONT> <FONT color=blue>Event</FONT> TheEvent() 

   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> LàmViệc() 
      RaiseEvent TheEvent() 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Kế đó bạn dùng Menu command <B>File | Add Project | New 
    Project</B> để thêm một project mới với tên <B>EventClass</B>. Để có thể 
    dùng Class1, bạn cần phải reference nó với Menu command <B>Project | Add 
    Reference...</B>, chọn Tab <B>Projects</B> và click <B>Browse</B> để chọn 
    <B>ClassLibrary1.DLL</B> từ subfolder <B>ClassLibrary1\bin</B> của solution 
    như trong hình dưới đây:</FONT></P>
    <BLOCKQUOTE>
      <P><FONT size=2><IMG height=446 src="7_files/EventClassDLL.gif" 
      width=566></FONT></P></BLOCKQUOTE>
    <P><FONT size=2>Một khi đã referenced ClassLibrary1 với Class1 trong ấy, bây 
    giờ bạn có thể doubleclick lên Form1 để code như sau:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Private</FONT> <FONT color=blue>WithEvents</FONT> obj <FONT color=blue>As</FONT> ClassLibrary1.Class1 

<FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> Form1_Load( <FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object,  _
                       <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> MyBase.Load 
   obj = <FONT color=blue>New</FONT> ClassLibrary1.Class1() 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Nhớ là ta phải declare variable <B>obj</B> thuộc loại 
    <B>ClassLibrary1.Class1</B> với <B>WithEvents</B>. Đặt một Button tên 
    BtnLàmViệc và doubleclick lên nó để code như sau:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> BtnLàmViệc_Click( <FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object, _
                                <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> BtnLàmViệc.Click 
   obj.LàmViệc() 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Để xử lý Event của <B>obj</B> bạn chọn tên từ combobox phía 
    trên bên trái, rồi chọn <B>TheEvent</B> từ combobox bên phải như trong hình 
    dưới đây:</FONT></P>
    <BLOCKQUOTE>
      <P><FONT size=2><IMG height=338 src="7_files/HandleEvent.gif" 
      width=765></FONT></P></BLOCKQUOTE>
    <P><FONT size=2>Ở đây ta handle Event bằng cách hiển thị một message đơn 
    giản: <B>Đang xử lý một Event từ Class1</B>. Bây giờ bạn có thể chạy 
    program. Khi bạn click Button BtnLàmViệc program sẽ hiển thị message để 
    chứng minh rằng từ một Application ta có thể handle event trong Class của 
    một Project khác.</FONT></P>
    <BLOCKQUOTE>
      <P><FONT size=2><IMG height=183 src="7_files/Event.gif" 
      width=302></FONT></P></BLOCKQUOTE>
    <P><FONT size=2>Bạn có thể <A 
    href="http://www.vovisoft.com/dotNET/Bai07/RaiseEvent.zip">Download source 
    code</A> của program nầy tại đây.<BR><BR></FONT></P></FONT>
    <BLOCKQUOTE>
      <HR>
      <FONT face=Arial>
      <H3><FONT size=2>Ghi chú</FONT></H3>
      <P><FONT size=2>Nếu sau khi Unzip source file và load project vào, bạn 
      dùng IDE Menu command <B>Build | Rebuild Solution</B> để compile lại hết 
      các modules nhưng gặp error về references thì hãy làm như sau: </FONT></P>
      <UL>
        <LI><FONT size=2>Trong Solution Explorer click các tree nodes 
        <B>references</B> để tìm các references có dấu chấm thang trong tam giác 
        vàng và remove chúng. </FONT>
        <LI><FONT size=2>Dùng Menu command <B>Project | Add Reference...</B> để 
        chọn <B>*.dll</B> lại từ một <B>\bin</B> subfolder. </FONT>
        <LI><FONT size=2>Rebuild Solution. </FONT></LI></UL>
      <BLOCKQUOTE>
        <P><FONT size=2><IMG height=349 src="7_files/RemoveRef.gif" 
        width=275></FONT></P></BLOCKQUOTE>
      <P><FONT size=2>Nếu bạn dùng chữ Việt Unicode trong program thì nhớ set up 
      <B>Advanced Save Option</B> với Menu command <B>File</B> như trong hình 
      dưới đây:</FONT></P>
      <BLOCKQUOTE>
        <P><FONT size=2><IMG height=474 src="7_files/AdvancedSave.gif" 
        width=224></FONT></P></BLOCKQUOTE>
      <P><FONT size=2>Khi Dialog hiện ra, bạn chọn <B>Unicode (UTF-8)</B> cho 
      <B>Encoding</B>: </FONT></P>
      <BLOCKQUOTE>
        <P><FONT size=2><IMG height=165 src="7_files/AdvancedSaveDialog.gif" 
        width=338></FONT></P></BLOCKQUOTE>
      <P><FONT size=2>Nếu bạn không thấy có menuItem Advanced Save Option trong 
      Menu File thì cứ dùng menuItem <B>Save As...</B> rồi click lên combo box 
      <B>Save</B> phía dưới, bên phải của Save File As Dialog rồi chọn <B>Save 
      with Encoding...</B> như trong hình dưới đây:</FONT></P>
      <BLOCKQUOTE>
        <P><FONT size=2><IMG height=412 src="7_files/SaveWithEncoding.gif" 
        width=662></FONT></P></BLOCKQUOTE>
      <P><FONT size=2>Nếu bạn quên set up Advanced Save Option như trên, chữ 
      Việt sẽ bị lưu trử dưới dạng ANSI nên một số sẽ mất dấu chữ Việt và thay 
      vào đó bằng những dấu <B>?</B>. </FONT></P></FONT>
      <HR>
    </BLOCKQUOTE><FONT face=Arial>
    <H3><FONT color=#800000 size=2>Shared Events</FONT></H3>
    <P><B><FONT size=2>Events</FONT></B><FONT size=2> có thể được declared là 
    <B>Shared</B>. <B>Shared methods</B> chỉ có thể raise shared events, chúng 
    không thể raise non-shared events. Thí dụ như:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> NguồnEvent 
   <FONT color=blue>Shared</FONT> <FONT color=blue>Event</FONT> EventDùngChoSharedMethods() 

   <FONT color=blue>Public</FONT> <FONT color=blue>Shared</FONT> <FONT color=blue>Sub</FONT> DùngChung() 
      RaiseEvent EventDùngChoSharedMethods() 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Một shared event có thể được raised bởi cả shared methods lẫn non-shared 
    methods:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> NguồnEvent 
   <FONT color=blue>Public</FONT> <FONT color=blue>Event</FONT> TheEvent() 
   <FONT color=blue>Shared</FONT> <FONT color=blue>Event</FONT> EventDùngChoSharedMethods() 

   <FONT color=blue>Public</FONT> <FONT color=blue>Shared</FONT> <FONT color=blue>Sub</FONT> DùngChung() 
      RaiseEvent EventDùngChoSharedMethods() 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 

   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> LàmViệc() 
      RaiseEvent TheEvent() 
      RaiseEvent EventDùngChoSharedMethods() 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Nếu bạn tìm cách raise một non-shared event từ một shared 
    method thì sẽ bị syntax error. </FONT></P>
    <H3><FONT color=blue size=2>Early Binding hay Late Binding (Hiệu lực Sớm hay 
    Trể) </FONT></H3>
    <P><B><FONT size=2>Early Binding</FONT></B><FONT size=2> có nghĩa là program 
    biết rõ ngay từ đầu loại Object (thuộc Class nào) sẽ được dùng trong hoàn 
    cảnh nào. Nó cho phép IntelliSense hiển thị cho ta thấy những class members 
    nào ta có thể dùng và compiler kiểm xem những methods ta dùng có hiện hữu 
    không. Early Binding code được compiled ra IL rất hiệu năng vì compiler biết 
    rõ ràng data types của các parameters.<BR><BR>Ngược lại <B>Late Binding</B> 
    có nghĩa là ta làm việc cách linh động với một Object lúc run-time, tức là 
    program không biết trước Object ấy thuộc loại nào. Late Binding cho ta sự 
    uyển chuyển chỉ làm sao Object cung cấp đúng method cần thiết là đủ. Do đó, 
    ta không hưởng được sự sang trọng IntelliSense cung cấp và compiler không 
    thể kiểm soát loại Object trước dùm cho ta được. Mặc dầu Late Binding code 
    chạy chậm hơn nhưng nó cho ta sự tự do giống như khi làm việc ngoài đời, để 
    đến giờ chót mới xác nhận.<BR><BR>By Default, mọi objects trong VB.NET đều 
    là Late Bound. Visual Studio.NET IDE với <B>Option Strict Off</B> by default 
    áp đặt luật đó. Nếu muốn áp đặt Early Binding ta cần phải nhét câu <B>Option 
    Strict On</B> ở đầu một source file. </FONT></P>
    <H3><FONT color=#800000 size=2>Dùng Object Type</FONT></H3>
    <P><FONT size=2>Ta có Late Binding khi compiler không thể xác định loại 
    Object ta đang gọi. Ta có thể thực hiện điều nầy bằng cách dùng <B>Object 
    Type</B> để tuyên bố một cách mơ hồ rằng ta sẽ dùng một loại Object nào đó, 
    vì một variable với Object type có thể hold-reference-to bất cứ một Object 
    nào. Do đó, những dòng code sau đây có thể được dùng cho bất cứ Object nào 
    mà Class của nó có implement <B>Sub CôngTácTôi</B> và không dùng parameter 
    nào cả:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Option</FONT> Strict Off 

<FONT color=blue>Module</FONT> LateBind 
   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> LàmViệc( <FONT color=blue>ByVal</FONT> obj <FONT color=blue>As</FONT> Object) 
      obj.CôngTácTôi() 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Module</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Nếu <B>obj</B> passed vào <B>Sub LàmViệc</B> không có một <B>Sub 
    CôngTácTôi</B> chẳng dùng parameter nào hết thì program sẽ bị error lúc 
    run-time. Do đó, ta nên luôn luôn dùng một <B>Try Structure</B> để bắt cái 
    error đó. Thí dụ như:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Option</FONT> Strict Off 

<FONT color=blue>Module</FONT> LateBind 
   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> LàmViệc( <FONT color=blue>ByVal</FONT> obj <FONT color=blue>As</FONT> Object) 
      <FONT color=blue>Try</FONT> 
         obj.CôngTácTôi() 
      <FONT color=blue>Catch</FONT> e <FONT color=blue>As</FONT> Exception 
        <FONT color=green>' Code để xử lý trường hợp Object không thích hợp</FONT>
         Console.WriteLine("Invalid Object passed to LàmViệc") 
      <FONT color=blue>End</FONT> <FONT color=blue>Try</FONT> 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Module</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <H3><FONT color=#800000 size=2>Late Binding và Reflection</FONT></H3>
    <P><FONT size=2>.NET framework hổ trợ một ý niệm gọi là <B>reflection</B>. 
    Nó nói đến khả năng của program kiểm tra .NET code để biết trong code có 
    những thứ gì. Ta dùng namespace <B>System.Reflection</B> để viết code làm 
    chuyện ấy.<BR><BR>Với System.Reflection ta có thể viết code để khám phá 
    những classes nằm trong một <B>assembly</B>, để biết mỗi class có những 
    methods, properties và events nào. Tiếp theo đó, ta có thể dùng reflection 
    để instantiate và dùng những objects từ các classes ấy. Cả quá trình nầy 
    hoàn toàn linh động - giống hệt như Late Binding.</FONT></FONT><FONT 
    face=Tahoma><I></P><FONT face=Arial size=2>
    <P>Thật ra, CLR (Common Language Runtime) dùng reflection để implement Late 
    Binding dùm cho chúng ta. Thay vì bắt chúng ta phải tự dùng reflection để 
    code Late Binding, .NET đã tử tế lo lắng chuyện ấy một cách tự động cho 
    chúng ta.</P></FONT></I><FONT face=Arial>
    <H3><FONT color=#800000 size=2>Dùng Function CType</FONT></H3>
    <P><FONT size=2>Dầu ta có dùng Late Binding hay không, nhiều khi rất tiện để 
    ta pass reference đến một object nào đó, từ chỗ nầy đến chỗ khác, bằng cách 
    dùng Data Type <B>Object</B> tổng quát - khi nào cần dùng nó thì ta đổi nó 
    ra đúng loại Object trong hoàn cảnh. Ta thực hiện việc convert data type 
    bằng cách dùng <B>Function CType</B>, điều đó cho phép ta nói trước Data 
    Type Object sẽ được converted ra object của class nào để gọi một method theo 
    cách <B>Early Bound</B>:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Module</FONT> LateBind 
   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> LàmViệc( <FONT color=blue>ByVal</FONT> obj <FONT color=blue>As</FONT> Object) 
       CType(obj, TheClass).CôngTácTôi() 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Module</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Trong thí dụ trên dù rằng ta đang làm việc với variable thuộc type Object 
    - trên nguyên tắc thì có vẽ là <B>Late Bound</B> - nhưng chúng ta đang dùng 
    <B>Function CType</B> để convert <B>obj</B> ra một object thuộc class 
    <B>TheClass</B>.<BR><BR>Kỹ thuật nầy được gọi là <B>casting</B> (đổ khuôn). 
    Nếu ta xem <B>TheClass</B> như một cái khuôn, khi ta ép <B>obj</B> vào khuôn 
    ấy thì giống như đổ khuôn để cho obj có dạng của TheClass.<BR><BR>Function 
    CType rất hữu dụng khi ta làm việc với những objects có implement nhiều 
    <B>interfaces</B>, vì ta có thể dùng cùng một object cho những interfaces 
    khác nhau. Giả dụ như ta có một object thuộc loại TheClass và nó cũng có 
    implement một interface tên <B>MyInterface</B>, ta có thể dùng interface ấy 
    trong code sau đây:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Dim</FONT> obj <FONT color=blue>As</FONT> TheClass 
obj = <FONT color=blue>New</FONT> TheClass 
CType(obj, MyInterface).DoSomething() 

</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Theo cách trên ta có thể gọi methods theo cách Early Bound 
    trong nhiều interfaces của một object mà không cần phải declare một variable 
    mới. </FONT></P>
    <H3><FONT color=blue size=2>Thừa kế từ một ngôn ngữ khác</FONT></H3>
    <P><FONT size=2>VB.NET code được compile ra IL (Intermediate Language) 
    managed code, tức là code sẽ được CLR (Common Language Runtime) chạy trong 
    .NET Framework. Mọi managed code, không cần biết được compiled từ ngôn ngữ 
    nào đều có thể làm việc chung nhau, tức là ta có thể tạo một class trong 
    ngôn ngữ nầy và dùng nó trong một ngôn ngữ khác, kể cả việc thừa 
    kế.</FONT></P>
    <P><I><FONT size=2>Thật ra hầu như ta luôn luôn làm việc ấy khi viết VB.NET. 
    Đó là vì phần lớn .NET system library<BR>được viết bằng C#, nhưng ta dùng 
    hay thừa kế từ nó thường xuyên trong VB.NET.</FONT></I></P>
    <H3><FONT color=#800000 size=2>Tạo một VB.NET BaseClass</FONT></H3>
    <P><FONT size=2>Trong thí dụ về thừa kế từ một ngôn ngữ khác, trứớc hết ta 
    thử tạo một Class Library Project trong VB.NET tên <B>vblib</B> và thêm vào 
    đó một class đơn giản tên <B>Parent</B> giống như sau:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Public</FONT> <FONT color=blue>Class</FONT> Parent 
   <FONT color=blue>Public</FONT> <FONT color=blue>Sub</FONT> SayHello() 
      MsgBox("Hello from Parent Class", MsgBoxStyle.Information, "Parent Class in VB.NET") 
   <FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
<FONT color=blue>End</FONT> <FONT color=blue>Class</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Ta sẽ dùng Parent làm BaseClass để thừa kế thành một 
    SubClass trong C#. </FONT></P>
    <H3><FONT color=#800000 size=2>Tạo một C# SubClass</FONT></H3>
    <P><FONT size=2>Dùng <B>File | Add Project</B> để thêm một C# Class Library 
    project mới và đặt tên nó là <B>cslib</B>. Reference vblib bằng cách dùng 
    Menu command <B>Project | Add Reference...</B> và chọn Tab Projects, click 
    Browse để tìm <B>vblib.dll</B> trong <B>vblib\bin</B> subfolder. </FONT></P>
    <P><I><FONT size=2>Lưu ý là ta vừa mới reference vblib.dll, cái assembly của 
    Class Parent, chớ ta không đụng đến hay cần VB.NET source code của Class 
    Parent. Trong C#, ta sẽ thừa kế Class Parent qua reference BaseClass trong 
    vblib.dll assembly.</FONT></I></P>
    <P><FONT size=2>Bây giờ code C# như sau:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>namespace</FONT> cslib
{
  <FONT color=blue>using</FONT> System.Windows.Forms;
  <FONT color=blue>using</FONT> vblib;

  <FONT color=blue>public class</FONT> cSharpclass <FONT color=blue>:</FONT> Parent
  {
    <FONT color=blue>public</FONT> cSharpclass()
    {
       MessageBox.Show("Instantiating cSharpclass object, inheriting VB.NET Parent class", "CSharp Class");
    }
  }
}
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Code C# bên trên có nhiều điểm tương đồng với VB.NET. Tuy 
    nhiên vì C# đến từ ngôn ngữ lập trình C và C++ nên nó có syntax hơi khác một 
    chút: </FONT></P>
    <UL>
      <LI><FONT size=2>Mọi statement trong C# phải chấm dứt bằng dấu <B>;</B> để 
      đánh dấu cuối hàng </FONT>
      <LI><FONT size=2>Cặp dấu ngoặc cong queo <B>{ .. }</B> được dùng để đánh 
      dấu đầu và cuối của một Statement Block thay vì dùng <B>End Sub</B>. 
      </FONT>
      <LI><FONT size=2>Keyword <B>using</B> được dùng thay vì keyword 
      <B>Imports</B> trong VB.NET </FONT>
      <LI><FONT size=2>C# thì <B>case sensitive</B>, tức là phân biệt chữ hoa, 
      chữ thường - thí dụ <B>obj</B> thì khác với <B>Obj</B>. </FONT>
      <LI><FONT size=2>Constructor method mang cùng tên với class thay vì tên 
      <B>New</B> như trong VB.NET. </FONT></LI></UL>
    <P><FONT size=2>Ta hãy thử đi qua các dòng code. Câu thứ nhất định nghĩa 
    namespace cho source file. Trong C#, mọi namespace phải được tuyên bố rõ 
    ràng (explicitly declared) trong mỗi code module.</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>namespace</FONT> cslib
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Kế đó là hai câu tuyên bố ta nhập khẩu System.Windows.Forms và 
    vblib:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial>  <FONT color=blue>using</FONT> System.Windows.Forms;
  <FONT color=blue>using</FONT> vblib;
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Câu kế đó tuyên bố cSharpclass thừa kế từ class Parent, để ý cách dùng 
    dấu <B>:</B> thay vì keyword <B>Inherits</B>:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial>  <FONT color=blue>public class</FONT> cSharpclass <FONT color=blue>:</FONT> Parent
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial size=2>
    <P>Sau cùng là Constructor dùng chính tên của class:<BR></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial>    <FONT color=blue>public</FONT> cSharpclass()
    {
       MessageBox.Show("Instantiating cSharpclass object, inheriting VB.NET Parent class", "CSharp Class");
    }
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Để ý cách dùng <B>MessageBox.Show</B> giống hệt như trong 
    VB.NET để hiển thị một message. </FONT></P>
    <H3><FONT color=#800000 size=2>Tạo một program Client</FONT></H3>
    <P><FONT size=2>Dùng menu command <B>File | Add Project</B> để thêm một 
    VB.NET Windows Application project mới cho solution. Trong project mới nầy 
    ta dùng menu command <B>Project | Add Reference...</B> để thêm references 
    cho <B>cslib</B> và <B>vblib</B>. Right-click lên project trong Solution 
    Explorer và chọn nó làm <B>Set As Startup Project</B> để project nầy chạy 
    khi ta bấm <I>F5</I>.<BR><BR>Bây giờ đặt một Button tên BtnStartDemo lên 
    Form và viết code dưới đây để xử lý Event Click:</FONT></P></FONT>
    <TABLE bgColor=#f6f6f6>
      <TBODY>
      <TR>
        <TD><FONT size=3><PRE><FONT face=Arial><FONT color=blue>Private</FONT> <FONT color=blue>Sub</FONT> BtnStartDemo_Click( <FONT color=blue>ByVal</FONT> sender <FONT color=blue>As</FONT> System.Object,  _
                                      <FONT color=blue>ByVal</FONT> e <FONT color=blue>As</FONT> System.EventArgs) <FONT color=blue>Handles</FONT> BtnStartDemo.Click 
   <FONT color=blue>Dim</FONT> objCS <FONT color=blue>As</FONT> <FONT color=blue>New</FONT> cslib.cSharpclass() 
   objCS.SayHello() 
<FONT color=blue>End</FONT> <FONT color=blue>Sub</FONT> 
</FONT></PRE></FONT></TD></TR></TBODY></TABLE><FONT face=Arial>
    <P><FONT size=2>Khi ta chạy program và click button StartDemo ta sẽ thấy một 
    dialog cho biết Constructor của cSharpclass đang được gọi để instantiate 
    object <B>objCS</B>: </FONT></P>
    <BLOCKQUOTE>
      <P><FONT size=2><IMG height=209 src="7_files/CSharpClass.gif" 
      width=424></FONT></P></BLOCKQUOTE>
    <P><FONT size=2>Tiếp theo đó một dialog thứ nhì hiển thị message từ Sub 
    SayHello mà objCS thừa kế từ BaseClass Parent:</FONT></P>
    <BLOCKQUOTE>
      <P><FONT size=2><IMG height=221 src="7_files/ParentClass.gif" 
      width=297></FONT></P></BLOCKQUOTE>
    <P><FONT size=2>Bạn có thể <A 
    href="http://www.vovisoft.com/dotNET/Bai07/CrossLanguageInheritance.zip">Download 
    source code</A> của program nầy tại đây. </FONT></P>
    <H3><FONT color=blue size=2>Thừa kế hình ảnh (Visual 
Inheritance)</FONT></H3>
    <P><FONT size=2>Cho đến bây giờ ta đã bàn qua chức năng OO của ngôn ngữ 
    VB.NET, phần lớn nhắm vào đặc tính thừa kế.<BR><BR>Vì các hình ảnh (Visual 
    Components) trong VB.NET được implemented bằng ngôn ngữ lập trình chính quy 
    chớ không phải dùng một cách thức khác biệt như trong VB6 (tin tức diễn tả 
    các hình ảnh nằm ở phần đầu các <B>*.frm</B> files), nên VB.NET cũng hổ trợ 
    <B>Thừa kế hình ảnh (Visual Inheritance) </B>cho Windows Forms một cách tự 
    nhiên. Điều nầy có nghĩa là sau khi làm xong một Windows Form với những 
    Textboxes, Labels, Listboxes ..v.v.. ta có thể thừa kế nó rồi để vô thêm các 
    hình ảnh khác. Ta sẽ bàn vô chi tiết về chuyện nầy trong tương 
    lai.<BR><BR>Ta cũng có thể thừa kế từ chính các hình ảnh. Thí dụ ta có thể 
    thừa kế từ một Textbox để tạo ra một class Textbox mới, có thêm chức năng 
    nhận keystrokes theo cách VNI và hiển thị chữ Việt Unicode.<BR><BR>Cùng một 
    nguyên tắc thừa kế nầy của Windows Forms Controls cũng áp dụng cho <B>Web 
    Forms Controls</B>, tức là ta có thể SubClass một Web Forms Control, cho 
    thêm các chức năng mới và overriding một số chức năng có 
    sẵn.</FONT></P></FONT></FONT></FONT><!-- Start of bottom bar for copyright notice etc -->
    <TABLE class=clsNavLinks id=tblFooterLinks cellSpacing=0 cellPadding=0 
    width="100%" border=0>
      <TBODY>
      <TR>
        <TD class=clsRaised width=785 bgColor=#6699cc colSpan=5>
          <P><FONT face=Arial color=#ffffff size=2>Vovisoft © 2000. All rights 
          reserved.</FONT></P></TD></TR>
      <TR>
        <TD width=256>
          <P><FONT face=Arial size=2>&nbsp;&nbsp; Last Updated: <!--webbot 
      bot="Timestamp" S-Type="REGENERATED" S-Format="%d %b %Y" startspan -->07 
          th3 2002<!--webbot 
      bot="Timestamp" endspan i-checksum="13302" --> </FONT></P></TD>
        <TD width=181><FONT face=Arial size=2>&nbsp;</FONT></TD>
        <TD width=258>
          <P><FONT face=Arial size=2><A 
          href="mailto:dixon@vovisoft.com">Webmaster</A></FONT></P></TD></TR></TBODY></TABLE></BLOCKQUOTE></BLOCKQUOTE>
<HR>

<P align=center><FONT face="Times New Roman"><B><FONT color=#ff0000>PcLeHoan 
1996 - 2002</FONT><FONT face=.VnTime size=2><BR></FONT></B></FONT><FONT 
face="Times New Roman" size=2><B>Mirror </B>: <A 
href="http://www.pclehoan.com/andi/ndc.htm">http://www.pclehoan.com/andi/ndc.htm</A><BR><B>Mirror 
</B>: <A 
href="http://www.lehoanpc.net/andi/ndc.htm">http://www.lehoanpc.net/andi/ndc.htm</A></FONT><BR><FONT 
face="Times New Roman" size=2><B>Mirror </B>: <A 
href="http://www.ktlehoan.com/">http://www.ktlehoan.com/</A></FONT></P>
<P align=center><A target=_top 
href="http://member.bcentral.com/cgi-bin/fc/fastcounter-login?2828564"><IMG 
src="7_files/digits.gif" border=0></A> </P></BODY></HTML>
